
#!/user/bin/python
# coding:utf-8
import nltk
import numpy
import jieba
import codecs

class Text_summary:
    def __init__(self):
        self.N = 100 #单词数量
        self.CLUSTER_THRESHOLD = 5 #单词间的距离
        self.TOP_SENTENCES = 7 #返回的top n句子

# N=100#单词数量
# CLUSTER_THRESHOLD=5#单词间的距离
# TOP_SENTENCES=5#返回的top n句子


    #停用词#分句
    def sent_tokenizer(self,texts):
        start=0
        i=0#每个字符的位置
        sentences=[]
        punt_list='.!?。！？' #'  ,.!?:;~，。！？：；～'.decode('utf8')
        for text in texts:
            if text in punt_list and token not in punt_list: #检查标点符号下一个字符是否还是标点
                sentences.append(texts[start:i+1])#当前标点符号位置
                start=i+1#start标记到下一句的开头
                i+=1
            else:
                i+=1#若不是标点符号，则字符位置继续前移
                token=list(texts[start:i+2]).pop()#取下一个字符
        if start<len(texts):
            sentences.append(texts[start:])#这是为了处理文本末尾没有标点符号的情况
        return sentences

    def load_stopwordslist(self,path):
        print('load stopwords...')
        stoplist=[line.strip() for line in codecs.open(path,'r',encoding='utf8').readlines()]
        stopwrods={}.fromkeys(stoplist)
        return stopwrods

    #摘要
    def summarize(self,text):
        stopwordPath= 'D:/gitee/abc_kg_nlp/data/dict/stopword.dict'
        stopwords=self.load_stopwordslist(stopwordPath)
        sentences=self.sent_tokenizer(text)
        print(sentences)
        words=[w for sentence in sentences for w in jieba.cut(sentence) if w not in stopwords if len(w)>1 and w!='\t']
        wordfre=nltk.FreqDist(words)
        topn_words=[w[0] for w in sorted(wordfre.items(),key=lambda d:d[1],reverse=True)][:self.N]
        scored_sentences=self._score_sentences(sentences,topn_words)
        #approach 1,利用均值和标准差过滤非重要句子
        avg=numpy.mean([s[1] for s in scored_sentences])#均值
        std=numpy.std([s[1] for s in scored_sentences])#标准差
        mean_scored=[(sent_idx,score) for (sent_idx,score) in scored_sentences if score>(avg+0.4*std)]
        #approach 2，返回top n句子
        top_n_scored=sorted(scored_sentences,key=lambda s:s[1])[-self.TOP_SENTENCES:]
        top_n_scored=sorted(top_n_scored,key=lambda s:s[0])
        return dict(top_n_summary=[sentences[idx] for (idx,score) in top_n_scored],mean_scored_summary=[sentences[idx] for (idx,score) in mean_scored])

     #句子得分
    def _score_sentences(self,sentences,topn_words):
        scores=[]
        sentence_idx=-1
        for s in [list(jieba.cut(s)) for s in sentences]:
            sentence_idx+=1
            word_idx=[]
            for w in topn_words:
                try:
                    word_idx.append(s.index(w))#关键词出现在该句子中的索引位置
                except ValueError:#w不在句子中
                    pass
            word_idx.sort()
            if len(word_idx)==0:
                continue
            #对于两个连续的单词，利用单词位置索引，通过距离阀值计算族
            clusters=[]
            cluster=[word_idx[0]]
            i=1
            while i<len(word_idx):
                if word_idx[i]-word_idx[i-1]<self.CLUSTER_THRESHOLD:
                    cluster.append(word_idx[i])
                else:
                    clusters.append(cluster[:])
                    cluster=[word_idx[i]]
                i+=1
            clusters.append(cluster)
            #对每个族打分，每个族类的最大分数是对句子的打分
            max_cluster_score=0
            for c in clusters:
                significant_words_in_cluster=len(c)
                total_words_in_cluster=c[-1]-c[0]+1
                score=1.0*significant_words_in_cluster*significant_words_in_cluster/total_words_in_cluster
                if score>max_cluster_score:
                    max_cluster_score=score
            scores.append((sentence_idx,max_cluster_score))
        return scores;


if __name__=='__main__':
    text_summary = Text_summary()
    dict=text_summary.summarize(u'报告期内，在安全技术研究领域，公司取得了新的进展，包括：（1）启明星辰ADLab发布《黑雀攻击--揭秘“Death”僵尸网络背后的终极控制者》分析报告，提出“黑雀”攻击概念。'
                   u'报告通过数据的统计分析、逆向分析并结合样本特征逐一揭秘“ Death ”僵尸网络中的黑吃黑乱象及隐藏于僵尸网络中的“黑雀”攻击、“Death”僵尸的黑客产业链，'
                   u'以及“Death”僵尸与Nitol僵尸和鬼影僵尸的关系。'
                   u'（2）在2017年1月举行的“2016中国智能交通行业年度评选颁奖典礼”上，启明星辰获得“中国智能交通行业信息安全优秀服务商奖”及“2016年度中国智能交通行业领军企业”两项大奖'
                   u'（3）2017年2月24日，2017中国自动化产业年会（CAIAC2017）召开，启明星辰工控异常监测系统被评为“CAIAC2017年度最具竞争力创新产品”。 '
                   u'这是继工业防火墙获“2015中国自动化领域十大年度最具竞争力创新产品”后，启明星辰工控安全能力再次获得市场的肯定。'
                   u'（4）启明星辰下一代入侵防御系统（启明星辰NGIPS）通过CNNVD的兼容性认证，标志着启明星辰NGIPS产品得到了国家权威漏洞库的支持和认可。'
                   u'启明星辰NGIPS通过与CNNVD的合作和攻击知识库共享，进一步提升产品对新型威胁的响应能力，能够让客户及时应对国内特有的漏洞利用攻击，大大提升了安全管理水平。'
                   u'（5）2017年3月17日，国家信息安全漏洞共享平台（CNVD）2017年工作会议在北京隆重召开，会议对CNVD漏洞工作进行了全面总结，并对相关单位进行了表彰。'
                   u'启明星辰荣获“2016年漏洞信息报送突出贡献单位”、“2016年原创漏洞报送突出贡献单位” 以及“年度最有价值漏洞”三项大奖。'
                   u'（6）2017年4月25日，由工业和信息化部指导、中国通信企业协会与中国信息通信研究院联合主办的“2017年（第七届）电信和互联网行业网络安全年会”召开。'
                   u'主办方公布了2017年度电信和互联网行业项目奖“网络安全服务优秀案例”和个人奖“网络安全服务之星”两大类奖项，其中，启明星辰公司荣获4项项目奖、3项个人奖，奖项总数位居第一。'
                   u'（7）5月21日至22日，国家计算机网络应急技术处理协调中心（以下简称“CNCERT”）举行第七届网络安全应急服务支撑单位选拔会议，启明星辰再次获得国家级网络安全应急服务支撑单位称号。'
                   u'报告期内，在产品方面，公司也有多项新举措：（1）在过去的2016年三大国内电信运营商相继发布了大数据安管平台的规范要求，使大数据背景下的运营商安全管理需求持续发酵，'
                   u'启明星辰泰合本部结合在大数据领域的技术研究和积累，充分提炼在安管平台的技术领先性，在满足规范的基础版本上发布了全新的安全管理平台大数据版。产品采用全新技术架构，'
                   u'\n融合业界流行的大数据技术，针对高速信息进行采集，融合多源异构数据，结合SQL、NewSQL和NoSQL技术，实现异构海量安全数据的高效可靠存储，并以安全数据为驱动，'
                   u'提供智能化关联分析技术和基于机器学习的行为分析技术。系统内建主动安全管理机制，通过主动的漏洞扫描和安全配置核查，及时发现业务信息系统中存在的隐患和风险，并进行事前预警；'
                   u'结合内外部情报协作，提供更加准确和及时的安全分析。（2）4月16日，启明星辰泰合北斗团队发布了《启明星辰泰合安全管理平台针对最新NSA黑客工具泄漏事件的应急处置指引》，'
                   u'介绍了将会受泄漏的NSA工具控制受影响的Windows主机类型与可利用SMB、RDP、IIS等服务漏洞进行攻击的行为，并给出了相应的应急处置指引。针对本次全球范围内爆发的“WannaCry”勒索病毒事件，'
                   u'启明星辰提供基于安全管理平台的事件分析和安全预警操作指导。'
                   u'（3）4月27日，启明星辰在北京“429首都网络安全日”活动上发布了一款保护中小企业信息安全的产品—云子可信安全云平台（https://www.cloudtrust.com.cn/home）。'
                   u'云子可信安全云平台是一款为了解决中小企业现有难题所研发的产品，不需购买服务器、带宽，也不需配备专业安全运维人员，只要接入互联网，即可获取该平台的所有安全服务。'
                   u'云子可信是启明星辰公司打造的第一款SaaS产品，其搭建快、成本低、需专业IT维护的特点为企业解决自身的信息安全难题提供了捷径，'
                   u'强大的终端安全管理能力、良好的用户体验与可达性和高效的P2P客户端升级方式，为一个企业获得快速稳定的经济增长提供了有力保障')

    print('-----------approach 1-------------')
    for sent in dict['top_n_summary']:
        print(sent)
    print('-----------approach 2-------------')
    for sent in dict['mean_scored_summary']:
        print(sent)

